home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 2.iso / STUTTGART / NEWSOFT / MAY / MP3CONV / !MP3Conv / c / musicout < prev    next >
Text File  |  1998-04-08  |  25KB  |  755 lines

  1. /**********************************************************************
  2.  * ISO MPEG Audio Subgroup Software Simulation Group (1996)
  3.  * ISO 13818-3 MPEG-2 Audio Decoder - Lower Sampling Frequency Extension
  4.  *
  5.  * $Id: musicout.c,v 1.2 1996/03/28 03:13:37 rowlands Exp $
  6.  *
  7.  * $Log: musicout.c,v $
  8.  * Revision 1.2  1996/03/28 03:13:37  rowlands
  9.  * Merged layers 1-2 and layer 3 revisions
  10.  *
  11.  * Revision 1.1  1996/02/14 03:45:52  rowlands
  12.  * Initial revision
  13.  *
  14.  * Received from FhG
  15.  **********************************************************************/
  16. /**********************************************************************
  17.  *   date   programmers                comment                        *
  18.  * 2/25/91  Douglas Wong        start of version 1.0 records          *
  19.  * 3/06/91  Douglas Wong        rename setup.h to dedef.h             *
  20.  *                              removed extraneous variables          *
  21.  *                              removed window_samples (now part of   *
  22.  *                              filter_samples)                       *
  23.  * 3/07/91  Davis Pan           changed output file to "codmusic"     *
  24.  * 5/10/91  Vish (PRISM)        Ported to Macintosh and Unix.         *
  25.  *                              Incorporated new "out_fifo()" which   *
  26.  *                              writes out last incomplete buffer.    *
  27.  *                              Incorporated all AIFF routines which  *
  28.  *                              are also compatible with SUN.         *
  29.  *                              Incorporated user interface for       *
  30.  *                              specifying sound file names.          *
  31.  *                              Also incorporated user interface for  *
  32.  *                              writing AIFF compatible sound files.  *
  33.  * 27jun91  dpwe (Aware)        Added musicout and &sample_frames as  *
  34.  *                              args to out_fifo (were glob refs).    *
  35.  *                              Used new 'frame_params' struct.       *
  36.  *                              Clean,simplify, track clipped output  *
  37.  *                              and total bits/frame received.        *
  38.  * 7/10/91  Earle Jennings      changed to floats to FLOAT            *
  39.  *10/ 1/91  S.I. Sudharsanan,   Ported to IBM AIX platform.           *
  40.  *          Don H. Lee,                                               *
  41.  *          Peter W. Farrett                                          *
  42.  *10/ 3/91  Don H. Lee          implemented CRC-16 error protection   *
  43.  *                              newly introduced functions are        *
  44.  *                              buffer_CRC and recover_CRC_error      *
  45.  *                              Additions and revisions are marked    *
  46.  *                              with "dhl" for clarity                *
  47.  * 2/11/92  W. Joseph Carter    Ported new code to Macintosh.  Most   *
  48.  *                              important fixes involved changing     *
  49.  *                              16-bit ints to long or unsigned in    *
  50.  *                              bit alloc routines for quant of 65535 *
  51.  *                              and passing proper function args.     *
  52.  *                              Removed "Other Joint Stereo" option   *
  53.  *                              and made bitrate be total channel     *
  54.  *                              bitrate, irrespective of the mode.    *
  55.  *                              Fixed many small bugs & reorganized.  *
  56.  *19 aug 92 Soren H. Nielsen    Changed MS-DOS file name extensions.  *
  57.  * 8/27/93 Seymour Shlien,      Fixes in Unix and MSDOS ports,        *
  58.  *         Daniel Lauzon, and                                         *
  59.  *         Bill Truerniet                                             *
  60.  *--------------------------------------------------------------------*
  61.  * 4/23/92  J. Pineda           Added code for layer III.  LayerIII   *
  62.  *          Amit Gulati         decoding is currently performed in    *
  63.  *                              two-passes for ease of sideinfo and   *
  64.  *                              maindata buffering and decoding.      *
  65.  *                              The second (computation) pass is      *
  66.  *                              activated with "decode -3 <outfile>"  *
  67.  * 10/25/92 Amit Gulati         Modified usage() for layerIII         *
  68.  * 12/10/92 Amit Gulati         Changed processing order of re-order- *
  69.  *                              -ing step.  Fixed adjustment of       *
  70.  *                              main_data_end pointer to exclude      *
  71.  *                              side information.                     *
  72.  *  9/07/93 Toshiyuki Ishino    Integrated Layer III with Ver 3.9.    *
  73.  *--------------------------------------------------------------------*
  74.  * 11/20/93 Masahiro Iwadare    Integrated Layer III with Ver 4.0.    *
  75.  *--------------------------------------------------------------------*
  76.  *  7/14/94 Juergen Koller      Bug fixes in Layer III code           *
  77.  *--------------------------------------------------------------------*
  78.  * 08/11/94 IIS                 Bug fixes in Layer III code           *
  79.  *--------------------------------------------------------------------*
  80.  * 11/04/94 Jon Rowlands        Prototype fixes                       *
  81.  *--------------------------------------------------------------------*
  82.  *  7/12/95 Soeren H. Nielsen   Changes for LSF Layer I and II        *
  83.  *--------------------------------------------------------------------*
  84.  *  7/14/94 Juergen Koller      Bug fixes in Layer III code           *
  85.  *--------------------------------------------------------------------*
  86.  *     8/95 Roland Bitto        addapdet to MPEG 2                    *
  87.  *--------------------------------------------------------------------*
  88.  * 11/22/95 Heiko Purnhagen     skip ancillary data in bitstream      *
  89.  *--------------------------------------------------------------------*
  90.  * 12/16/96 Johan Hagman    Adapted for Solaris (mpeg3play 0.9)   *
  91.  **********************************************************************/
  92.  
  93. #include        "common.h"
  94. #include        "decoder.h"
  95. #include    "sound.h"
  96.  
  97. /********************************************************************
  98.  *
  99.  *        This part contains the MPEG I decoder for Layers I & II.
  100.  *
  101.  *********************************************************************/
  102.  
  103. /****************************************************************
  104.  *
  105.  *        For MS-DOS user (Turbo c) change all instance of malloc
  106.  *        to _farmalloc and free to _farfree. Compiler model hugh
  107.  *        Also make sure all the pointer specified are changed to far.
  108.  *
  109.  *****************************************************************/
  110. /* local functions definition */
  111.  
  112. static void usage(int level);
  113. static void GetArguments();
  114.  
  115. /*********************************************************************
  116.  *
  117.  * Core of the Layer II decoder.  Default layer is Layer II.
  118.  *
  119.  *********************************************************************/
  120.  
  121. /* Global variable definitions for "musicout.c" */
  122.  
  123. char        *programName;
  124. Arguments_t     Arguments;
  125. int         audiofd;
  126.  
  127. /* Implementations */
  128.  
  129. int main(int argc, char **argv)
  130. {
  131.     typedef unsigned int SAM[2][3][SBLIMIT];
  132.     static SAM FAR    *sample;
  133.  
  134.     typedef REAL     FRA[2][3][SBLIMIT];
  135.     static FRA FAR    *fraction;
  136.  
  137.     typedef short     PCMBUF[2][SSLIMIT][SBLIMIT];
  138.     static PCMBUF FAR    *pcm_sample;
  139.  
  140.     static Bit_stream_struc bs;
  141.     frame_params     fr_ps;
  142.     layer         info;
  143.     FILE        *musicout;        /* decode to file */
  144.     unsigned long     sample_frames;
  145.  
  146.     static int          i, j, k, stereo,
  147.              done = FALSE, clip, sync,
  148.              error_protection, crc_error_count,
  149.              total_error_count;
  150.     static unsigned int     old_crc, new_crc;
  151.     static unsigned int     bit_alloc[2][SBLIMIT],
  152.              scfsi[2][SBLIMIT],
  153.              scale_index[2][3][SBLIMIT];
  154.     unsigned long     bitsPerSlot = 0, samplesPerFrame = 0, frameNum = 0;
  155.     unsigned long     frameBits, gotBits = 0;
  156.     IFF_AIFF         pcm_aiff_data;
  157.     int             Max_gr;
  158.  
  159.     III_scalefac_t     III_scalefac;
  160.     III_side_info_t     III_side_info;
  161.  
  162. #ifdef    MACINTOSH
  163.     console_options.nrows = MAC_WINDOW_SIZE;
  164.     argc = ccommand(&argv);
  165. #endif
  166.  
  167.     /* Most large variables are declared dynamically to ensure
  168.        compatibility with smaller machines */
  169.  
  170.     pcm_sample = (PCMBUF FAR *) mem_alloc((long) sizeof(PCMBUF),
  171.                                               "PCM Sample");
  172.     sample = (SAM FAR *) mem_alloc((long) sizeof(SAM), "Sample");
  173.     fraction = (FRA FAR *) mem_alloc((long) sizeof(FRA), "fraction");
  174.  
  175.     fr_ps.header = &info;
  176.     fr_ps.tab_num = -1;                /* no table loaded */
  177.     fr_ps.alloc = NULL;
  178.  
  179.     Arguments.topSb = 0;
  180.     Arguments.forkoff = 0;
  181.     GetArguments(argc, argv, &Arguments);
  182.  
  183.     if (Arguments.forkoff) {
  184. #ifndef RISCOS
  185.     switch (fork()) {
  186.     case 0:
  187.         break;    /* child continues*/
  188.     case -1:
  189.         perror("fork");
  190.         exit(-1);
  191.         break;
  192.     default:
  193.         return 0;    /* parent returns*/
  194.     }
  195. #else
  196.         fprintf(stderr,"Not supported on RISCOS\n");
  197.         exit(-1);
  198. #endif
  199.     }
  200.  
  201.     if (Arguments.write_to_file) {
  202.     if (strcmp(Arguments.decoded_file_name, "-") == 0)
  203.         musicout = stdout;
  204.     else {
  205.         if ((musicout = fopen(Arguments.decoded_file_name, "w+b")) == NULL) {
  206.         fprintf(stderr, "Could not create \"%s\".\n", Arguments.decoded_file_name);
  207.         exit(1);
  208.         }
  209.     }
  210.     } else {
  211.     /* Open audio device write-only (to avoid buffering input data) */
  212.     if( (audiofd = sound_open()) < 0) {
  213.         perror("open audio device");
  214.         exit(1);
  215.     }
  216.     }
  217.     open_bit_stream_r(&bs, Arguments.encoded_file_name, BUFFER_SIZE);
  218.  
  219.     if (Arguments.need_aiff)
  220.     if (aiff_seek_to_sound_data(musicout) == -1) {
  221.         if (strcmp(Arguments.decoded_file_name, "-") == 0)
  222.         fprintf(stderr, "Could not seek to PCM sound data in stdout\n");
  223.         else
  224.         fprintf(stderr, "Could not seek to PCM sound data in \"%s\"\n",
  225.             Arguments.decoded_file_name);
  226.         exit(1);
  227.     }
  228.  
  229.     sample_frames = 0;
  230.  
  231.     /* The output loop */
  232.     while (!end_bs(&bs)) {
  233.  
  234.     sync = seek_sync(&bs, SYNC_WORD, SYNC_WORD_LNGTH);
  235.     frameBits = sstell(&bs) - gotBits;
  236.     if (frameNum > 0)        /* don't want to print on 1st loop; no lay */
  237.         if(frameBits % bitsPerSlot)
  238.         fprintf(stderr, "Got %ld bits = %ld slots plus %ld\n",
  239.              frameBits, frameBits/bitsPerSlot, frameBits%bitsPerSlot);
  240.     gotBits += frameBits;
  241.  
  242.     if (!sync) {
  243.         if (Arguments.verbose) {
  244.         fprintf(stderr,
  245.             "\rFrame %ld cannot be located, input stream may be empty\n",
  246.             frameNum);
  247.         }
  248.         done = TRUE;
  249.         /* Finally write out the buffer */
  250.         if (info.lay != 1)
  251.         out_fifo(*pcm_sample, 3, &fr_ps, done, musicout,
  252.                 &sample_frames);
  253.         else
  254.         out_fifo(*pcm_sample, 1, &fr_ps, done, musicout,
  255.                 &sample_frames);
  256.         break;
  257.     }
  258.  
  259.     decode_info(&bs, &fr_ps);
  260.     hdr_to_frps(&fr_ps);
  261.     stereo = fr_ps.stereo;
  262.     if (fr_ps.header->version == MPEG_PHASE2_LSF)
  263.         Max_gr = 1;
  264.     else
  265.         Max_gr = 2;
  266.  
  267.     error_protection = info.error_protection;
  268.     crc_error_count = 0;
  269.     total_error_count = 0;
  270.  
  271.     if (frameNum == 0) {
  272.         if (Arguments.verbose)
  273.         WriteHdr(&fr_ps, stderr);    /* printout layer/mode */
  274.  
  275.         if (!Arguments.write_to_file) {
  276.         if (sound_init(audiofd, &info, stereo)) {
  277.             perror("Couldn't initialize audio device");
  278.             exit(1);
  279.         }
  280.         }
  281.     }
  282.  
  283. #ifdef ESPS
  284.     if (frameNum == 0 && Arguments.need_esps) {
  285.         esps_write_header(musicout,(long) sample_frames,
  286.         s_freq[info.version][info.sampling_frequency] * 1000,
  287.         (int) stereo, Arguments.decoded_file_name );
  288.     } /* MI */
  289. #endif
  290.  
  291.     if (Arguments.verbose && frameNum % 10 == 0) {
  292.         fprintf(stderr, "\rFrame %-3lu ", frameNum);
  293.     }
  294.  
  295.     frameNum++;
  296.  
  297.     if (error_protection)
  298.         buffer_CRC(&bs, &old_crc);
  299.  
  300.     switch(info.lay) {
  301.     case 1:
  302.         bitsPerSlot = 32;
  303.         samplesPerFrame = 384;
  304.  
  305.         I_decode_bitalloc(&bs,bit_alloc,&fr_ps);
  306.         I_decode_scale(&bs, bit_alloc, scale_index, &fr_ps);
  307.  
  308.         if (error_protection) {
  309.         I_CRC_calc(&fr_ps, bit_alloc, &new_crc);
  310.         if (new_crc != old_crc) {
  311.             crc_error_count++;
  312.             total_error_count++;
  313.             recover_CRC_error(*pcm_sample, crc_error_count,
  314.                     &fr_ps, musicout, &sample_frames);
  315.             break;
  316.         }
  317.         else crc_error_count = 0;
  318.         }
  319.  
  320.         clip = 0;
  321.         for (i = 0; i < SCALE_BLOCK; i++) {
  322.         I_buffer_sample(&bs, (*sample), bit_alloc,&fr_ps);
  323.         I_dequantize_sample(*sample, *fraction, bit_alloc,&fr_ps);
  324.         I_denormalize_sample((*fraction),scale_index,&fr_ps);
  325. #ifdef DEBUG
  326.         if (Arguments.topSb > 0)     /* clear channels to 0 */
  327.            for (j = Arguments.topSb; j < fr_ps.sblimit; ++j)
  328.               for (k = 0; k < stereo; ++k)
  329.              (*fraction)[k][0][j] = 0.0;
  330. #endif
  331.         for (j = 0; j < stereo; j++) {
  332.            clip += SubBandSynthesis(&((*fraction)[j][0][0]), j,
  333.                          &((*pcm_sample)[j][0][0]));
  334.         }
  335.         out_fifo(*pcm_sample, 1, &fr_ps, done,
  336.              musicout, &sample_frames);
  337.          }
  338.          if (clip > 0 && Arguments.verbose)
  339.         fprintf(stderr, "\rFrame %-3lu: %d output samples clipped\n",
  340.                 frameNum - 1, clip);
  341.          break;
  342.  
  343.     case 2:
  344.         bitsPerSlot = 8;
  345.         samplesPerFrame = 1152;
  346.  
  347.         II_decode_bitalloc(&bs, bit_alloc, &fr_ps);
  348.         II_decode_scale(&bs, scfsi, bit_alloc, scale_index, &fr_ps);
  349.  
  350.         if (error_protection) {
  351.         II_CRC_calc(&fr_ps, bit_alloc, scfsi, &new_crc);
  352.         if (new_crc != old_crc) {
  353.             crc_error_count++;
  354.             total_error_count++;
  355.             recover_CRC_error(*pcm_sample, crc_error_count,
  356.                 &fr_ps, musicout, &sample_frames);
  357.             break;
  358.         } else
  359.             crc_error_count = 0;
  360.          }
  361.  
  362.          clip = 0;
  363.          for (i = 0; i < SCALE_BLOCK; i++) {    /* SCALE_BLOCK = 12*/
  364.         II_buffer_sample(&bs, (*sample), bit_alloc, &fr_ps);
  365.         II_dequantize_sample((*sample), bit_alloc, (*fraction), &fr_ps);
  366.         II_denormalize_sample((*fraction), scale_index, &fr_ps, i>>2);
  367. #ifdef DEBUG
  368.         if (Arguments.topSb > 0)      /* debug : clear channels to 0 */
  369.             for (j=Arguments.topSb; j<fr_ps.sblimit; ++j)
  370.             for (k=0; k<stereo; ++k)
  371.                 (*fraction)[k][0][j] =
  372.                 (*fraction)[k][1][j] =
  373.                 (*fraction)[k][2][j] = 0.0;
  374. #endif
  375.         for (j = 0; j < 3; j++) {
  376.             for (k = 0; k < stereo; k++) {
  377.             clip += SubBandSynthesis(&((*fraction)[k][j][0]),
  378.                 k, &((*pcm_sample)[k][j][0]));
  379.             }
  380.         }
  381.         out_fifo(*pcm_sample, 3, &fr_ps, done, musicout,
  382.              &sample_frames);
  383.          }
  384.          if (clip > 0 && Arguments.verbose)
  385.         fprintf(stderr, "\rFrame %-3lu: %d output samples clipped\n",
  386.                 frameNum - 1, clip);
  387.          break;
  388.  
  389.     case 3: {
  390.         static int    nSlots;
  391.         static int    gr, ch, ss, sb,
  392.             main_data_end, flush_main;
  393.         static int    bytes_to_discard;
  394.         static int    frame_start = 0;
  395.  
  396.         bitsPerSlot = 8;
  397.         if (fr_ps.header->version == MPEG_PHASE2_LSF)
  398.         samplesPerFrame = 576;
  399.         else
  400.         samplesPerFrame = 1152;
  401.  
  402.         III_get_side_info(&bs, &III_side_info, &fr_ps);
  403.         nSlots = main_data_slots(fr_ps);
  404.  
  405.         for (; nSlots > 0; nSlots--)    /* read main data*/
  406.         hputbuf((unsigned int) getbits(&bs,8), 8);
  407.         main_data_end = hsstell() / 8;    /* of previous frame*/
  408.  
  409.         if ((flush_main = (hsstell() % bitsPerSlot))) {
  410.         hgetbits((int)(bitsPerSlot - flush_main));
  411.         main_data_end ++;
  412.         }
  413.         bytes_to_discard = frame_start - main_data_end -
  414.                    III_side_info.main_data_begin ;
  415.         if (main_data_end > 4096) {
  416.         frame_start -= 4096;
  417.         rewindNbytes(4096);
  418.         }
  419.  
  420.         frame_start += main_data_slots(fr_ps);
  421.         if (bytes_to_discard < 0) {
  422.         if (Arguments.verbose)
  423.             fprintf(stderr, "not enough main data to decode, "
  424.                  "frame discarded\n");
  425.         break;
  426.         }
  427.         for (; bytes_to_discard > 0; bytes_to_discard--)
  428.          hgetbits(8);
  429.  
  430.         clip = 0;
  431.         for (gr = 0; gr < Max_gr; gr++) {    /* 1 or 2*/
  432.         static REAL    lr[2][SBLIMIT][SSLIMIT],
  433.                 ro[2][SBLIMIT][SSLIMIT];
  434.  
  435.         for (ch = 0; ch < stereo; ch++) {
  436.             /* Quantized samples*/
  437.             static long int is[SBLIMIT+1][SSLIMIT];
  438.             int part2_start;
  439.  
  440.             part2_start = hsstell();
  441.             if (fr_ps.header->version != MPEG_PHASE2_LSF)
  442.             III_get_scale_factors(&III_scalefac,
  443.                 &III_side_info,    gr, ch, &fr_ps);
  444.             else
  445.             III_get_LSF_scale_factors(&III_scalefac,
  446.                 &III_side_info, gr,ch,&fr_ps);
  447.  
  448.             III_hufman_decode(is, &III_side_info, ch, gr, part2_start,
  449.                 &fr_ps);
  450.             III_dequantize_sample(is, ro[ch], &III_scalefac,
  451.                 &(III_side_info.ch[ch].gr[gr]), ch, &fr_ps);
  452.         }
  453.         III_stereo(ro, lr, &III_scalefac,
  454.                 &(III_side_info.ch[0].gr[gr]), &fr_ps);
  455.  
  456.         for (ch = 0; ch < stereo; ch++) {
  457.             static REAL re[SBLIMIT][SSLIMIT];
  458.             /* Hybrid filter input*/
  459.             static REAL hybridIn[SBLIMIT][SSLIMIT];
  460.             /* Hybrid filter out*/
  461.             static REAL hybridOut[SBLIMIT][SSLIMIT];
  462.             /* PolyPhase Input*/
  463.             static REAL polyPhaseIn[SBLIMIT];
  464.  
  465.             III_reorder(lr[ch],re,&(III_side_info.ch[ch].gr[gr]),
  466.                   &fr_ps);
  467.  
  468.             III_antialias(re, hybridIn,        /* antialias butterflies*/
  469.                   &(III_side_info.ch[ch].gr[gr]), &fr_ps);
  470.  
  471.             for (sb = 0; sb < SBLIMIT; sb++) {    /* hybrid synthesis*/
  472.             III_hybrid(hybridIn[sb], hybridOut[sb], sb, ch,
  473.                    &(III_side_info.ch[ch].gr[gr]), &fr_ps);
  474.             }
  475.  
  476. #ifdef OPTIMIZE
  477.             for (ss = 0; ss < SSLIMIT; ss++) {    /* Polyphase synthesis*/
  478.             for (sb = 0; sb < SBLIMIT; sb++) {
  479.                 /* Perform frequency inversion for polyphase*/
  480.                 if ((ss % 2) && (sb % 2))
  481.                 polyPhaseIn[sb] = -hybridOut[sb][ss];
  482.                 else
  483.                 polyPhaseIn[sb] = hybridOut[sb][ss];
  484.             }
  485.             clip += SubBandSynthesis(polyPhaseIn, ch,
  486.                         &((*pcm_sample)[ch][ss][0]));
  487.             }
  488. #else
  489.             /* Frequency inversion for polyphase*/
  490.             for (ss = 0; ss < SSLIMIT; ss++)        /* 18*/
  491.             for (sb = 0; sb < SBLIMIT; sb++)    /* 32*/
  492.                 if ((ss%2) && (sb%2))
  493.                 hybridOut[sb][ss] = -hybridOut[sb][ss];
  494.  
  495.             for (ss = 0; ss < SSLIMIT; ss++) {    /* Polyphase synthesis*/
  496.             for (sb = 0; sb < SBLIMIT; sb++)
  497.                 polyPhaseIn[sb] = hybridOut[sb][ss];
  498.             clip += SubBandSynthesis (polyPhaseIn, ch,
  499.                         &((*pcm_sample)[ch][ss][0]));
  500.             }
  501. #endif    /* OPTIMIZE */
  502.         }
  503.         /* Output PCM sample points for one granule*/
  504.         out_fifo(*pcm_sample, 18, &fr_ps, done, musicout,
  505.              &sample_frames);
  506.         }
  507.         if (clip > 0 && Arguments.verbose)
  508.         fprintf(stderr, "\rFrame %-3lu: %d output samples clipped\n",
  509.                 frameNum - 1, clip);
  510.  
  511.         } /* end of layer 3 block*/
  512.         break;
  513.  
  514.     } /* end of case*/
  515.  
  516. /* Commented out for now*/
  517. #if 0
  518.     /* Skip ancillary data   HP 22-nov-95 */
  519.     if (info.bitrate_index > 0) { /* if not free-format */
  520.         long anc_len;
  521.  
  522.         anc_len = (int)((double)samplesPerFrame /
  523.                    s_freq[info.version][info.sampling_frequency] *
  524.                    (double)bitrate[info.version][info.lay-1][info.bitrate_index] /
  525.                    (double)bitsPerSlot);
  526.         if (info.padding)
  527.             anc_len++;
  528.         anc_len *= bitsPerSlot;
  529.         anc_len -= sstell(&bs)-gotBits+SYNC_WORD_LNGTH;
  530.         for (j=0; j<anc_len; j++)
  531.             get1bit(&bs);
  532.     }
  533. #endif
  534.  
  535.     }
  536.  
  537.     if (Arguments.need_aiff) {
  538.     pcm_aiff_data.numChannels    = stereo;
  539.     pcm_aiff_data.numSampleFrames    = sample_frames;
  540.     pcm_aiff_data.sampleSize    = 16;
  541.     pcm_aiff_data.sampleRate    = (double)
  542.         s_freq[info.version][info.sampling_frequency] * 1000;
  543.     pcm_aiff_data.sampleType    = IFF_ID_SSND;
  544.     pcm_aiff_data.blkAlgn.offset    = 0;
  545.     pcm_aiff_data.blkAlgn.blockSize = 0;
  546.  
  547.     if (aiff_write_headers(musicout, &pcm_aiff_data) == -1) {
  548.         if (strcmp(Arguments.decoded_file_name, "-") == 0)
  549.         fprintf(stderr, "Could not write AIFF headers to stdout\n");
  550.         else
  551.         fprintf(stderr, "Could not write AIFF headers to \"%s\"\n",
  552.             Arguments.decoded_file_name);
  553.         exit(2);
  554.     }
  555.     }
  556.  
  557.     if (Arguments.verbose)
  558.     fprintf(stderr, "\r%ld frames, avg slots/frame = %.3f; b/smp = %.2f; br = %.3f kbps\n",
  559.         frameNum, (float) gotBits / (frameNum * bitsPerSlot),
  560.         (float) gotBits / (frameNum * samplesPerFrame),
  561.         (float) gotBits / (frameNum * samplesPerFrame) *
  562.         s_freq[info.version][info.sampling_frequency]);
  563.  
  564.     close_bit_stream_r(&bs);
  565.     if (Arguments.write_to_file)
  566.     fclose(musicout);
  567.     else {
  568.     if (sound_close(audiofd))
  569.         perror("Error closing audio device");
  570.     }
  571.  
  572.     /* for the correct AIFF header information */
  573.     /*             on the Macintosh            */
  574.     /* the file type and the file creator for  */
  575.     /* Macintosh compatible Digidesign is set  */
  576.  
  577. #ifdef  MACINTOSH
  578.     if (Arguments.need_aiff)
  579.         set_mac_file_attr(Arguments.decoded_file_name, VOL_REF_NUM,
  580.                                      CREATR_DEC_AIFF, FILTYP_DEC_AIFF);
  581.     else    set_mac_file_attr(Arguments.decoded_file_name, VOL_REF_NUM,
  582.                                      CREATR_DEC_BNRY, FILTYP_DEC_BNRY);
  583. #endif
  584.  
  585.     if (Arguments.verbose) {
  586.     fprintf(stderr, "Decoding of \"%s\" is finished\n",
  587.         Arguments.encoded_file_name);
  588.     if (Arguments.write_to_file) {
  589.         if (strcmp(Arguments.decoded_file_name, "-") == 0)
  590.         fprintf(stderr, "The decoded PCM output was written to stdout\n");
  591.         else
  592.         fprintf(stderr, "The decoded PCM output file name is \"%s\"\n",
  593.             Arguments.decoded_file_name);
  594.     }
  595.     }
  596.     return 0;
  597. }
  598.  
  599. static void usage(int level)    /* print help info and exit*/
  600. {
  601.     if (level >= 1) {
  602.     fprintf(stderr,
  603.     "+---------------------------------------+\n"
  604.     "|   mpeg3play version 0.9.6, 6-Apr-97   |\n"
  605.     "+---------------------------------------+\n"
  606.     "This is an MPEG audio layer 2 and layer 3 decoder/player\n"
  607.     "based on public ISO/MPEG audio decoder source code. Solaris\n"
  608.     "port and optimizations by Johan.Hagman@mailbox.swipnet.se.\n\n"
  609.     "Copyright (C) 1996, 1997 by Johan Hagman.\n"
  610.     "This program is free software.\n\n");
  611.     }
  612. #ifdef DEBUG
  613.     fprintf(stderr, "usage: %s [-v] [-h] [-f] [-o outfile.aiff] [-s sb] filename\n",
  614.         programName);
  615. #else
  616. # ifdef AMIGA
  617.     fprintf(stderr, "usage: %s [-v] [-h] [-f] [-r] [-o outfile.aiff] filename\n",
  618.         programName);
  619. # else
  620.     fprintf(stderr, "usage: %s [-v] [-h] [-f] [-o outfile.aiff] filename\n",
  621.         programName);
  622. # endif
  623. #endif
  624.     fprintf(stderr,"  -v          enable verbose mode\n");
  625.     fprintf(stderr,"  -h          display program help information\n");
  626.     fprintf(stderr,"  -f          fork off new player and return\n");
  627. #ifdef AMIGA
  628.     fprintf(stderr,"  -r          switch to raw PCM (amiga)\n");
  629. #endif
  630.     fprintf(stderr,"  -o outfile  write an AIFF output PCM sound file\n");
  631. #ifdef DEBUG
  632.     fprintf(stderr,"  -s sb       resynth only up to this subband (debugging)\n");
  633. #endif
  634.     fprintf(stderr,"  filename    bit stream of encoded audio (\"-\" means stdin)\n");
  635.     exit(1);
  636. }
  637.  
  638.  
  639. static void GetArguments(int argc, char **argv, Arguments_t *Arguments)
  640. {
  641.     int        i = 0, err = 0, raw_output = FALSE;
  642.  
  643.     programName = "mpeg3play";
  644.  
  645.     Arguments->need_aiff = FALSE;
  646.     Arguments->need_esps = FALSE;    /* MI */
  647.     Arguments->write_to_file= FALSE;
  648.     Arguments->verbose = FALSE;
  649.  
  650.     Arguments->encoded_file_name[0] = '\0';
  651.     Arguments->decoded_file_name[0] = '\0';
  652.  
  653.     while (++i < argc && err == 0) {
  654.     char c, *token, *arg, *nextArg;
  655.     int  argUsed;
  656.  
  657.     token = argv[i];
  658.     /* Original code was if (*token++ == '-'), this change makes*/
  659.     /* it possible to use "-" for reading input stream from stdin*/
  660.     if (*token++ == '-' && *token != '\0') {
  661.         if (i+1 < argc)
  662.         nextArg = argv[i+1];
  663.         else
  664.         nextArg = "";
  665.         argUsed = 0;
  666.         while ((c = *token++)) {
  667.         if (*token /* NumericQ(token) */)
  668.             arg = token;
  669.         else
  670.             arg = nextArg;
  671.         switch(c) {
  672.         case 'v':
  673.             Arguments->verbose = TRUE;
  674.             break;
  675.         case 'h':
  676.             usage(1);
  677.             break;
  678.         case 'f':
  679.             Arguments->forkoff = TRUE;
  680.             break;
  681. #ifdef AMIGA
  682.         case 'r':
  683.             raw_output = TRUE;
  684.             break;
  685. #endif
  686.         case 'o':
  687.             argUsed = 1;    /* eat one arg*/
  688.             if (*arg == '\0') {
  689.             fprintf(stderr,"error: -o requires a filename arg\n");
  690.             err = 1;    /* found no filename*/
  691.             } else {
  692.             strcpy(Arguments->decoded_file_name, arg);
  693.  
  694.             if (raw_output)       /* set only by Amiga -r switch */
  695.                 Arguments->need_aiff = FALSE;
  696.             else
  697.                 Arguments->need_aiff = TRUE;
  698.  
  699.             Arguments->write_to_file = TRUE;
  700.             }
  701.             break;
  702. #ifdef DEBUG
  703.         case 's':
  704.             Arguments->topSb = atoi(arg);
  705.             argUsed = 1;
  706.             if (Arguments->topSb < 1 || Arguments->topSb > SBLIMIT) {
  707.             fprintf(stderr, "%s: -s band %s not %d..%d\n",
  708.                     programName, arg, 1, SBLIMIT);
  709.             err = 1;
  710.             }
  711.             break;
  712. #endif
  713.         default:
  714.             fprintf(stderr,"error: unrecognized option \"%c\"\n", c);
  715.             err = 1;
  716.             break;
  717.         }
  718.         if (argUsed) {
  719.             if (arg == token)
  720.             token = "";    /* no more from token */
  721.             else
  722.             ++i;        /* skip arg we used */
  723.             arg = "";
  724.             argUsed = 0;
  725.         }
  726.         } /* end while*/
  727.  
  728.     } else { /* end of options*/
  729.  
  730.         if (Arguments->encoded_file_name[0] == '\0') {
  731.         strcpy(Arguments->encoded_file_name, argv[i]);
  732.         } else {
  733.             fprintf(stderr, "error: excess arg \"%s\"\n", argv[i]);
  734.             err = 1;
  735.         }
  736.     }
  737.  
  738.     }
  739.  
  740.     if (err)
  741.     usage(0);
  742.     if (Arguments->encoded_file_name[0] == '\0') {
  743.         fprintf(stderr, "error: input file is missing\n");
  744.     usage(0);  /* never returns */
  745.     }
  746.  
  747.     if (Arguments->verbose && Arguments->need_aiff) {
  748.     if (strcmp(Arguments->decoded_file_name, "-") == 0)
  749.         fprintf(stderr, "The AIFF audio data is written to stdout\n");
  750.     else
  751.         fprintf(stderr, "The output file \"%s\" is written in AIFF format\n",
  752.             Arguments->decoded_file_name);
  753.     }
  754. }
  755.